package main

import (
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"mygoedu/day11/socket"
	"net"
	"net/http"
	"strconv"
	"time"
)

type WsServer struct {
	listener net.Listener
	addr     string
	upgrader *websocket.Upgrader
}

func NewWsServer(port int) *WsServer {
	ws := new(WsServer)
	ws.addr = "0.0.0.0:" + strconv.Itoa(port)
	ws.upgrader = &websocket.Upgrader{
		HandshakeTimeout:  2 * time.Second,
		ReadBufferSize:    1024,
		WriteBufferSize:   1024,
		WriteBufferPool:   nil,
		Subprotocols:      nil,
		Error:             func(w http.ResponseWriter, r *http.Request, status int, reason error) {},
		CheckOrigin:       func(r *http.Request) bool { return true },
		EnableCompression: false,
	}
	return ws
}

func (ws *WsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/add" {
		httpCode := http.StatusInternalServerError
		phrase := http.StatusText(httpCode) //解释错误码
		fmt.Printf("path error %s\n", r.URL.Path)
		http.Error(w, phrase, httpCode) //返回错误
		return
	}

	conn, err := ws.upgrader.Upgrade(w, r, nil) //升级http至websocket
	if err != nil {
		fmt.Printf("upgrade from http to websocket failed: %v\n", err)
		return
	}

	defer conn.Close()
	conn.SetReadDeadline(time.Now().Add(30 * time.Second))
	var request socket.Request
	for {
		err = conn.ReadJSON(&request)
		if err != nil {
			log.Printf("read error: %v\n", err)
			break
		}
		log.Printf("receive from client: %v\n", request)

		sum := request.A + request.B
		response := socket.Response{
			Sum: sum,
			Dur: 0,
		}
		err = conn.WriteJSON(response)
		socket.CheckError(err)
		log.Printf("send to client: %v\n", response)
	}

}

func main() {
	ws := NewWsServer(8080)
	listener, err := net.Listen("tcp", ws.addr)
	socket.CheckError(err)
	ws.listener = listener

	err = http.Serve(listener, ws) //阻塞运行
	socket.CheckError(err)

}
